From 250be0bb4a8e4550fdda38606a0a97ca3aa91129 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Mon, 2 Oct 2006 14:09:49 -0600 Subject: [PATCH] [IA64] Implement fast hypercall for physdevop eoi. Eoi is a very frequent hypercall which has only one argument passed through a structure. To avoid the xencomm overhead, a new hypercall is created and the argument is passed by value. Signed-off-by: Tristan Gingold --- .../include/asm-ia64/hypercall.h | 14 ++++- xen/arch/ia64/xen/hypercall.c | 51 +++++++++++-------- xen/include/asm-ia64/dom_fw.h | 7 +++ xen/include/public/arch-ia64.h | 3 ++ 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h index 169a2c03cf..8a21141179 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h @@ -259,6 +259,18 @@ xencomm_arch_hypercall_hvm_op(int cmd, void *arg) return _hypercall2(unsigned long, hvm_op, cmd, arg); } +static inline int +HYPERVISOR_physdev_op(int cmd, void *arg) +{ + switch (cmd) { + case PHYSDEVOP_eoi: + return _hypercall1(int, ia64_fast_eoi, + ((struct physdev_eoi *)arg)->irq); + default: + return xencomm_hypercall_physdev_op(cmd, arg); + } +} + extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); static inline void exit_idle(void) {} #define do_IRQ(irq, regs) ({ \ @@ -377,7 +389,6 @@ HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn, #define HYPERVISOR_multicall xencomm_mini_hypercall_multicall #define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version #define HYPERVISOR_console_io xencomm_mini_hypercall_console_io -#define HYPERVISOR_physdev_op xencomm_mini_hypercall_physdev_op #define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op #ifdef CONFIG_VMX_GUEST #define HYPERVISOR_memory_op 0 @@ -391,7 +402,6 @@ HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn, #define HYPERVISOR_multicall xencomm_hypercall_multicall #define HYPERVISOR_xen_version xencomm_hypercall_xen_version #define HYPERVISOR_console_io xencomm_hypercall_console_io -#define HYPERVISOR_physdev_op xencomm_hypercall_physdev_op #define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op #define HYPERVISOR_memory_op xencomm_hypercall_memory_op #endif diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index c9728f530b..8fc4c4c3cb 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -123,6 +123,20 @@ xen_hypercall (struct pt_regs *regs) return IA64_NO_FAULT; } +static IA64FAULT +xen_fast_hypercall (struct pt_regs *regs) +{ + uint32_t cmd = (uint32_t)regs->r2; + switch (cmd) { + case __HYPERVISOR_ia64_fast_eoi: + regs->r8 = pirq_guest_eoi(current->domain, regs->r14); + break; + default: + regs->r8 = -ENOSYS; + } + return IA64_NO_FAULT; +} + static void fw_hypercall_ipi (struct pt_regs *regs) { @@ -187,8 +201,8 @@ fw_hypercall_fpswa (struct vcpu *v) return PSCBX(v, fpswa_ret); } -static IA64FAULT -fw_hypercall (struct pt_regs *regs) +IA64FAULT +ia64_hypercall(struct pt_regs *regs) { struct vcpu *v = current; struct sal_ret_values x; @@ -199,7 +213,13 @@ fw_hypercall (struct pt_regs *regs) perfc_incra(fw_hypercall, index >> 8); switch (index) { - case FW_HYPERCALL_PAL_CALL: + case FW_HYPERCALL_XEN: + return xen_hypercall(regs); + + case FW_HYPERCALL_XEN_FAST: + return xen_fast_hypercall(regs); + + case FW_HYPERCALL_PAL_CALL: //printf("*** PAL hypercall: index=%d\n",regs->r28); //FIXME: This should call a C routine #if 0 @@ -250,7 +270,7 @@ fw_hypercall (struct pt_regs *regs) regs->r10 = y.v1; regs->r11 = y.v2; } break; - case FW_HYPERCALL_SAL_CALL: + case FW_HYPERCALL_SAL_CALL: x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33), vcpu_get_gr(v,34),vcpu_get_gr(v,35), vcpu_get_gr(v,36),vcpu_get_gr(v,37), @@ -258,46 +278,35 @@ fw_hypercall (struct pt_regs *regs) regs->r8 = x.r8; regs->r9 = x.r9; regs->r10 = x.r10; regs->r11 = x.r11; break; - case FW_HYPERCALL_SAL_RETURN: + case FW_HYPERCALL_SAL_RETURN: if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) ) vcpu_sleep_nosync(v); break; - case FW_HYPERCALL_EFI_CALL: + case FW_HYPERCALL_EFI_CALL: efi_ret_value = efi_emulator (regs, &fault); if (fault != IA64_NO_FAULT) return fault; regs->r8 = efi_ret_value; break; - case FW_HYPERCALL_IPI: + case FW_HYPERCALL_IPI: fw_hypercall_ipi (regs); break; - case FW_HYPERCALL_SET_SHARED_INFO_VA: + case FW_HYPERCALL_SET_SHARED_INFO_VA: regs->r8 = domain_set_shared_info_va (regs->r28); break; - case FW_HYPERCALL_FPSWA: + case FW_HYPERCALL_FPSWA: fpswa_ret = fw_hypercall_fpswa (v); regs->r8 = fpswa_ret.status; regs->r9 = fpswa_ret.err0; regs->r10 = fpswa_ret.err1; regs->r11 = fpswa_ret.err2; break; - default: + default: printf("unknown ia64 fw hypercall %lx\n", regs->r2); regs->r8 = do_ni_hypercall(); } return IA64_NO_FAULT; } -IA64FAULT -ia64_hypercall (struct pt_regs *regs) -{ - unsigned long index = regs->r2; - - if (index >= FW_HYPERCALL_FIRST_ARCH) - return fw_hypercall (regs); - else - return xen_hypercall (regs); -} - unsigned long hypercall_create_continuation( unsigned int op, const char *format, ...) { diff --git a/xen/include/asm-ia64/dom_fw.h b/xen/include/asm-ia64/dom_fw.h index 841ea9e200..baae6d08fc 100644 --- a/xen/include/asm-ia64/dom_fw.h +++ b/xen/include/asm-ia64/dom_fw.h @@ -39,6 +39,13 @@ #define FW_HYPERCALL_NUM_MASK_HIGH ~0xffUL #define FW_HYPERCALL_NUM_MASK_LOW 0xffUL +/* Xen hypercalls are 0-63. */ +#define FW_HYPERCALL_XEN 0x0000UL + +/* Define some faster and lighter hypercalls. + See definitions in arch-ia64.h */ +#define FW_HYPERCALL_XEN_FAST 0x0200UL + /* * PAL can be called in physical or virtual mode simply by * branching to pal_entry_point, which is found in one of the diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 08e2197846..aa51d3297d 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -428,6 +428,9 @@ struct xen_ia64_boot_param { #define HYPERPRIVOP_GET_PSR 0x19 #define HYPERPRIVOP_MAX 0x19 +/* Fast and light hypercalls. */ +#define __HYPERVISOR_ia64_fast_eoi 0x0200 + /* Xencomm macros. */ #define XENCOMM_INLINE_MASK 0xf800000000000000UL #define XENCOMM_INLINE_FLAG 0x8000000000000000UL -- 2.30.2